// ------
// Nirvana Toolkit
// description: 对象池
// ------

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Nirvana.Common
{
    public interface IPoolObject
    {
        public void OnGet();
        public void OnRelease();
    }

    public static class ObjectPool<T> where T : IPoolObject, new()
    {
        /// <summary>
        /// 对象的数量
        /// </summary>
        public static int countAll { get; private set; } = 0;
        /// <summary>
        /// 活动对象的数量
        /// </summary>
        public static int countActive => countAll - countInActive;
        /// <summary>
        /// 非活动对象的数量
        /// </summary>
        public static int countInActive => _pool.Count;

        /// <summary>
        /// 对象池本体
        /// </summary>
        private static readonly Stack<IPoolObject> _pool = new (150);

        /// <summary>
        /// 获取对象
        /// </summary>
        /// <returns></returns>
        public static T Get()
        {
            T obj;
            if (_pool.Count > 0)
            {
                obj = (T) _pool.Peek();
            }
            else
            {
                obj = new T();
                countAll++;
            }

            obj.OnGet();
            return obj;
        }

        /// <summary>
        /// 释放对象
        /// </summary>
        /// <param name="obj"></param>
        public static void Release(T obj)
        {
            if (_pool.Count > 0 && ReferenceEquals(_pool.Peek(), obj))
            {
                Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
            }
            obj.OnRelease();
            _pool.Push(obj);
        }
    }
}